Data Engineering Path · Airflow
What We Are Achieving Here?
The Pain Before Airflow
Before workflow orchestrators like Airflow existed though, data teams relied on a fragile mix of cron jobs, custom bash scripts, and manual coordination. This created an unmaintainable web of dependencies that inevitably broke at the worst possible time.
The Cron Job Nightmare
Consider a typical enterprise data pipeline before Airflow:
# crontab - the "old way" of scheduling
# No dependency management between jobs
# No visibility into failures
# No retry logic
# No alerting
# Extract sales data at 2:00 AM
0 2 * * * /scripts/extract_sales.sh >> /var/log/extract.log 2>&1
# Transform data at 3:00 AM (hope extract finished!)
0 3 * * * /scripts/transform_sales.sh >> /var/log/transform.log 2>&1
# Load to warehouse at 4:00 AM (hope transform finished!)
0 4 * * * /scripts/load_warehouse.sh >> /var/log/load.log 2>&1
# Generate reports at 5:00 AM (hope everything above worked!)
0 5 * * * /scripts/generate_reports.sh >> /var/log/reports.log 2>&1
What Could Go Wrong?
flowchart TD
A["2:00 AM - Extract starts"] --> B{"Did extract<br/>finish in time?"}
B -->|"Yes"| C["3:00 AM - Transform starts"]
B -->|"No"| D["Transform runs<br/>on stale data"]
C --> E{"Did transform<br/>succeed?"}
E -->|"Yes"| F["4:00 AM - Load starts"]
E -->|"No"| G["Load runs<br/>on corrupt data"]
F --> H{"Did load<br/>succeed?"}
H -->|"Yes"| I["5:00 AM - Reports generated"]
H -->|"No"| J["Reports show<br/>wrong numbers"]
J --> K["Wrong numbers reach<br/>the dashboard"]
style D fill:#F44336,stroke:#D32F2F,color:#fff
style G fill:#F44336,stroke:#D32F2F,color:#fff
style J fill:#F44336,stroke:#D32F2F,color:#fff
style K fill:#B71C1C,stroke:#880E4F,color:#fff
Caution
The fundamental problem with cron is time-based scheduling without dependency awareness. Cron doesn't know if the previous job succeeded, failed, or is still running. It just blindly fires at the scheduled time.
The fundamental problem with cron is time-based scheduling without dependency awareness. Cron doesn't know if the previous job succeeded, failed, or is still running. It just blindly fires at the scheduled time.
How Airflow Solves This
With Airflow, the same pipeline becomes dependency-aware, observable, and self-healing:
from airflow.sdk import DAG
from airflow.providers.standard.operators.python import PythonOperator
from airflow.providers.standard.operators.bash import BashOperator
from datetime import datetime, timedelta
with DAG(
dag_id="sales_etl",
schedule="0 2 * * *", # Start at 2:00 AM
start_date=datetime(2024, 1, 1),
catchup=False,
default_args={
"retries": 3, # Auto-retry on failure
"retry_delay": timedelta(minutes=10),
"email_on_failure": True, # Alert on failure
"email": ["oncall@company.com"],
},
) as dag:
extract = PythonOperator(
task_id="extract_sales",
python_callable=extract_from_source,
)
transform = PythonOperator(
task_id="transform_sales",
python_callable=transform_data,
)
load = PythonOperator(
task_id="load_to_warehouse",
python_callable=load_to_snowflake,
)
report = BashOperator(
task_id="generate_reports",
bash_command="python /scripts/generate_reports.py",
)
# Dependencies are explicit - no time-based guessing
extract >> transform >> load >> report
Cron vs Airflow — Feature Comparison
| Capability | Cron | Airflow |
|---|---|---|
| Scheduling | Time-based | Time-based + data-aware + event-driven |
| Dependencies | None | Explicit dependency graph |
| Retries | Manual | Automatic with configurable backoff |
| Monitoring | Log files only | Rich web UI with Grid, Graph, Gantt views |
| Alerting | Custom scripts | Built-in email, Slack, PagerDuty |
| Backfilling | Not supported | Native backfill with catchup=True |
| Parallelism | Manual process management | Configurable parallelism and pools |
| Version Control | Scattered scripts | Python files in Git |
| Testing | Not feasible | Unit tests with pytest |
| Scalability | Single machine | Distributed (Celery/Kubernetes) |
Tip
When evaluating Airflow for your team, the strongest arguments are usually: (1) visibility — everyone can see pipeline status in the UI, (2) reliability — retries and alerting prevent silent failures, and (3) maintainability — Python code is easier to review and test than bash scripts.
When evaluating Airflow for your team, the strongest arguments are usually: (1) visibility — everyone can see pipeline status in the UI, (2) reliability — retries and alerting prevent silent failures, and (3) maintainability — Python code is easier to review and test than bash scripts.
Real-World Impact
1000+
Companies using Airflow
35M+
Monthly PyPI Downloads
80+
Provider Packages
2800+
Contributors on GitHub